#pragma once
#include <algorithm>
#include <string>
#include <vector>
#include <map>

class Utils
{
public:
	template<typename c>
	static void deleteData(c& container)
	{
		std::for_each(container.begin(), container.end(), &deleteElement<c::value_type>);
	}

	template<typename c>
	static void deleteMap(c& map)
	{
		std::for_each(map.begin(), map.end(), &deleteElementOfMap<c::value_type>);
	}

	template<typename el>
	static el findByName(const std::vector<el>& v, const std::string& name)
	{
		for(std::vector<el>::const_iterator it = v.begin(); it != v.end(); it++)
		{
			if((*it)->getName() == name)
			{
				return *it;
			}
		}
		return NULL;
	}

	template<typename el>
	static el removeByName(std::vector<el>& v, const std::string& name)
	{
		for(std::vector<el>::const_iterator it = v.begin(); it != v.end(); it++)
		{
			if((*it)->getName() == name)
			{
				el result = *it;
				v.erase(it);
				return result;
			}
		}
		return NULL;
	}

	template<typename el>
	static el findByKey(const std::map<std::string, el>& map, const std::string& key)
	{
		for(std::map<std::string, el>::const_iterator it = map.begin(); it != map.end(); it++)
		{
			if(key == (*it).first)
			{
				return (*it).second;
			}
		}
		return NULL;
	}

		template<typename el>
	static el removeByKey(std::map<std::string, el>& map, const std::string& key)
	{
		for(std::map<std::string, el>::const_iterator it = map.begin(); it != map.end(); it++)
		{
			if(key == (*it).first)
			{
				el result = (*it).second;
				map.erase(it);
				return result;
			}
		}
		return NULL;
	}

private:
	template<typename el>
	static void deleteElement(el element)
	{
		try{
			delete element;
		}catch(...){}
	}

	template<typename el>
	static void deleteElementOfMap(el element)
	{
		try{
			delete element.second;
		}catch(...){}
	}
};
